﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Facebook;
using Facebook.Web;
using Newtonsoft.Json;
using ClusteringWrraper;
using Facebook.Properties;
using System.IO;

public partial class _Default : Page
{
    protected string requiredAppPermissions = "user_about_me,publish_stream";
    protected FacebookApp fbApp;
    protected CanvasAuthorizer authorizer;
    private int _uid;
    private string _token;
    private int _batchNum;
    private double _prec;
    private LoggedInUser _loggedInUser;
    private LinkedList<FriendsList> _result;
    
    protected void Page_Load(object sender, EventArgs e)
    {
        fbApp = new FacebookApp();
        authorizer = new CanvasAuthorizer(fbApp);
        authorizer.Perms = requiredAppPermissions;
        if (authorizer.Authorize())
        {
            ShowFacebookContent();
        }
    }

    private void ShowFacebookContent()
    {

        _uid = (int)fbApp.SignedRequest.UserId;

        _batchNum = 15;

        _token = fbApp.SignedRequest.AccessToken;

        _prec = 0.001;

        Directory.CreateDirectory("C:\\OUT");
        Directory.CreateDirectory("C:\\IN");
        Start();
    }

    private void Start()
    {

        string errMsg;
        var cleanResult = false;

        var cleanResultField = Request.QueryString.GetValues("clean");
        cleanResult = (cleanResultField != null);

        _loggedInUser = (LoggedInUser)Session["loggedInUser"];

        if (_loggedInUser == null)
        {
            _loggedInUser = new LoggedInUser(_token, _uid, _batchNum, _prec);
        }
        Session["loggedInUser"] = _loggedInUser;

        _result = (LinkedList<FriendsList>)Session["result"];
        if (_result == null || cleanResult)
        {
            _result = new LinkedList<FriendsList>();
            if (_loggedInUser.GetGroups() == null || _loggedInUser.GetGroups().Count == 0)
            {
                _loggedInUser.RunClustering(out errMsg);
            }
            foreach (var subGroup in _loggedInUser.GetGroups())
            {
                _result.AddLast(subGroup);
            }
            Session["result"] = new LinkedList<FriendsList>(_result);
        }else{
            _result = new LinkedList<FriendsList>(_result);
        }

        //If this is a split request then first split the group
        for (int i = 0; i < _result.Count; i++)
        {
            var friendList = _result.ElementAt(i);
            if (friendList.Count > 93)
            {
                int newGroups = SplitGroup(i+1);
                if (newGroups > 1)
                {
                    i += (newGroups - 1);
                }
            }
        }


        //If this is also a post to walls request then do it last
        var postIndexArr = Request.QueryString.GetValues("postIndex");
        if (postIndexArr != null)
        {
            foreach (var groupIndex in postIndexArr)
            {
                //var postMsg = ((TextBox)PreviousPage.FindControl("postTextBox" + groupIndex)).Text;
                var prevAccordion = PreviousPage.FindControl("accordion");
                var groupPanel = prevAccordion.FindControl("GpanelContainer" + groupIndex);
                if (groupPanel == null) return;
                var postPanel = groupPanel.FindControl("postPanel" + groupIndex);
                if (postPanel == null) return;
                var postTextBox = (TextBox)groupPanel.FindControl("postTextBox" + groupIndex);
                if (postTextBox == null) return;
                PostToGroupWalls(postTextBox.Text, Int32.Parse(groupIndex));
            }
        }

        UpdateUiWithResult();
    }

    private void UpdateUiWithResult()
    {
       
        /*var splitBtn = new Button();
        splitBtn.ID = "splitBtn";
        splitBtn.Text = "Split again";
        splitBtn.CausesValidation = false;
        splitBtn.UseSubmitBehavior = false;
        splitBtn.OnClientClick = @"window.top.location.href='https://apps.facebook.com/gmfriends/split.aspx'";

        SplitPanel.Controls.Add(new LiteralControl("<h3><a href='#sectionSplit'></a></h3><div>"));
        SplitPanel.Controls.Add(splitBtn);
        SplitPanel.Controls.Add(new LiteralControl("</div>"));*/

        int j = 0;
        int i = 0;
        foreach (var friendsList in _result)
        {
            j++;
            var groupPnl = new Panel();
            groupPnl.ScrollBars = ScrollBars.Auto;
            groupPnl.ID = "Gpanel" + j;
            //GroupPnl.BorderWidth = 1;
            //GroupPnl.BorderColor = System.Drawing.ColorTranslator.FromHtml("#f33398");
            groupPnl.Style.Add("float", "bottom");

            foreach (var user in friendsList)
            {
                i++;
                var friendPnl = new Panel();
                var friendIMG = new Image();
                var friendLbl = new Label();

                friendIMG.ID = "image" + j + i;
                friendPnl.ID = "panel" + j + i;
                friendLbl.ID = "name" + j + i;

                friendIMG.ImageUrl = user.Value.ImageUrl.Replace(@"\", "");

                friendIMG.BorderColor = System.Drawing.ColorTranslator.FromHtml("#3b5998");
                friendIMG.BorderWidth = 3;
                friendIMG.ToolTip = user.Value.Name.ToString();

                friendLbl.Width = 5;
                friendLbl.Height = 4;
                //friendLbl.Text = user.Name.ToString();

                //friendPnl.BorderColor = System.Drawing.ColorTranslator.FromHtml("#3b5998");
                //friendPnl.BorderWidth = 1;
                friendPnl.Style.Add("float", "left");


                friendPnl.Controls.Add(new LiteralControl(@"<a href=' http://www.facebook.com/profile.php?id=" + user.Value.Uid + @"' target='_parent'>"));
                friendPnl.Controls.Add(friendIMG);
                friendPnl.Controls.Add(new LiteralControl("</a>"));
                friendPnl.Controls.Add(new LiteralControl("<br/>"));
                friendPnl.Controls.Add(friendLbl);
                friendPnl.Style.Add("padding", "5px");

                groupPnl.Controls.Add(friendPnl);
            }

            var groupContainerPnl = new Panel();
            groupContainerPnl.ID = "GpanelContainer" + j;
            groupContainerPnl.Style.Add("float", "left");
            groupContainerPnl.Controls.Add(groupPnl);

            //var splitBtn = new Button();
            //splitBtn.ID = "splitBtn" + j;
            //splitBtn.Text = "Split this group";
            //splitBtn.PostBackUrl = "https://apps.facebook.com/gmfriends/?split=" + j;
            //splitBtn.CausesValidation = false;
            //splitBtn.UseSubmitBehavior = false;
            //splitBtn.Click += new System.EventHandler(splitBtn_Click);
            //splitBtn.OnClientClick = @"setTimeout(function(){alert('timer done');window.location.replace('Default.aspx?split=" + j + "');}, 2000)";
            //groupContainerPnl.Controls.AddAt(0, splitBtn);

            //Post panel
            var postPanel = new Panel();
            postPanel.ID = "postPanel" + j;
            postPanel.Style.Add("float", "bottom");
            var postTextBox = new TextBox();
            postTextBox.ID = "postTextBox" + j;
            postTextBox.Rows = 3;
            postPanel.Controls.Add(postTextBox);
            var postBtn = new Button();
            postBtn.ID = "postBtn" + j;
            postBtn.Text = "Post on their walls";
            postBtn.PostBackUrl = "https://apps.facebook.com/gmfriends/default.aspx?postIndex=" + j;
            postPanel.Controls.Add(postBtn);
            groupContainerPnl.Controls.AddAt(1, postPanel);

            accordion.Controls.Add(new LiteralControl("<h3><a href='#section" + j + "'>Group " + j + ":</a></h3><div>"));
            accordion.Controls.Add(groupContainerPnl);
            accordion.Controls.Add(new LiteralControl("</div>"));
        }

        //Lonely Friends:
        {
            var friendsList = _loggedInUser.GetLonelyFriends();
            var groupPnl = new Panel();
            groupPnl.ID = "Gpanel" + "LonelyFriends";
            //GroupPnl.BorderWidth = 1;
            //GroupPnl.BorderColor = System.Drawing.ColorTranslator.FromHtml("#f33398");
            groupPnl.Style.Add("float", "bottom");

            foreach (var user in friendsList)
            {
                i++;
                var friendPnl = new Panel();
                var friendIMG = new Image();
                var friendLbl = new Label();

                friendIMG.ID = "image" + "LonelyFriends" + i;
                friendPnl.ID = "panel" + "LonelyFriends" + i;
                friendLbl.ID = "name" + "LonelyFriends" + i;

                friendIMG.ImageUrl = user.Value.ImageUrl.Replace(@"\", "");

                friendIMG.BorderColor = System.Drawing.ColorTranslator.FromHtml("#3b5998");
                friendIMG.BorderWidth = 3;
                friendIMG.ToolTip = user.Value.Name.ToString();

                friendLbl.Width = 5;
                friendLbl.Height = 4;
                //friendLbl.Text = user.Name.ToString();

                //friendPnl.BorderColor = System.Drawing.ColorTranslator.FromHtml("#3b5998");
                //friendPnl.BorderWidth = 1;
                friendPnl.Style.Add("float", "left");


                friendPnl.Controls.Add(new LiteralControl(@"<a href=' http://www.facebook.com/profile.php?id=" + user.Value.Uid + @"' target='_parent'>"));
                friendPnl.Controls.Add(friendIMG);
                friendPnl.Controls.Add(new LiteralControl("</a>"));
                friendPnl.Controls.Add(new LiteralControl("<br/>"));
                friendPnl.Controls.Add(friendLbl);
                friendPnl.Style.Add("padding", "5px");

                groupPnl.Controls.Add(friendPnl);
            }

            var groupContainerPnl = new Panel();
            groupContainerPnl.ID = "GpanelContainer" + "LonelyFriends";
            groupContainerPnl.Style.Add("float", "left");
            groupContainerPnl.Controls.Add(groupPnl);

            accordion.Controls.Add(new LiteralControl("<h3><a href='#section" + "LonelyFriends" + "'>Friends with no mutual friends:</a></h3><div>"));
            accordion.Controls.Add(groupContainerPnl);
            accordion.Controls.Add(new LiteralControl("</div>"));   
        }
    }

    private void PostBtnOnClick(object sender, EventArgs eventArgs)
    {
        var btn = (Button)sender;
        var index = Int32.Parse(btn.ID.Substring(7));
        var groupPanel = accordion.FindControl("GpanelContainer" + index);
        if (groupPanel == null) return;
        var postPanel = groupPanel.FindControl("postPanel" + index);
        if (postPanel == null) return;
        var postTextBox = (TextBox)groupPanel.FindControl("postTextBox" + index);
        if (postTextBox == null) return;
        PostToGroupWalls(postTextBox.Text, index);
    }

    protected int SplitGroup(int groupIndex)
    {
        if (_loggedInUser == null)
            return 0;

        if (_loggedInUser.GetGroups() == null || _result.Count < groupIndex)
            return 0;

        var selectedGroup = _result.ElementAt(groupIndex - 1);//Groups starts at 1 and elements at 0
        var node = _result.Find(selectedGroup);
        if (node == null)
        {
            return 0;
        }

        selectedGroup.ClusterList();

        var groupSubGroups = selectedGroup.SubLists;

        foreach (var subGroup in groupSubGroups)
        {
            _result.AddAfter(node, subGroup);
        }

        _result.Remove(selectedGroup);

        return selectedGroup.SubLists.Count;
    }

    protected void PostToGroupWalls(string msg, int groupIndex)
    {
        if (_result == null || _loggedInUser == null)
        {
            return;
        }

        if (_loggedInUser.GetGroups() == null || _result.Count < groupIndex)
            return;

        var selectedGroup = _result.ElementAt(groupIndex - 1);

        selectedGroup.PostToGroupWallsWithRestApi(_token, msg);
    }

    protected void splitBtn_Click(object sender, EventArgs e)
    {
        var btn = (Button)sender;
        var index = btn.ID.Substring(8);
        //Page.Response.RedirectPermanent(@"https://apps.facebook.com/gmfriends/?split=" + index, true);
        Session["splitIndex"] = index;
    }
}